﻿#region License
//   Copyright 2010 John Sheehan
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License. 
#endregion

using System;
using RestSharp;
using RestSharp.Extensions;
using RestSharp.Validation;


namespace Twilio
{
	public partial class TwilioRestClient
	{
		/// <summary>
		/// Retrieve the details for a specific SMS message instance
		/// </summary>
		/// <param name="smsMessageSid">The Sid of the message to retrieve</param>
		/// <param name="callback">Method to call upon successful completion</param>
		public void GetSmsMessage(string smsMessageSid, Action<SMSMessage> callback)
		{
			var request = new RestRequest();
			request.Resource = "Accounts/{AccountSid}/SMS/Messages/{SMSMessageSid}";
			request.RootElement = "SMSMessage";
			request.AddUrlSegment("SMSMessageSid", smsMessageSid);

			ExecuteAsync<SMSMessage>(request, (response) => callback(response));
		}

		/// <summary>
		/// Returns a list of SMS messages. The list includes paging information and is sorted by DateSent, with most recent messages first.
		/// </summary>
		/// <param name="callback">Method to call upon successful completion</param>
		public void ListSmsMessages(Action<SmsMessageResult> callback)
		{
			ListSmsMessages(null, null, null, null, null, callback);
		}

		/// <summary>
		/// Returns a filtered list of SMS messages. The list includes paging information and is sorted by DateSent, with most recent messages first.
		/// </summary>
		/// <param name="to">(Optional) The phone number of the message recipient</param>
		/// <param name="from">(Optional) The phone number of the message sender</param>
		/// <param name="dateSent">(Optional) The date the message was sent (GMT)</param>
		/// <param name="pageNumber">(Optional) The page to start retrieving results from</param>
		/// <param name="count">(Optional) The number of results to retrieve</param>
		/// <param name="callback">Method to call upon successful completion</param>
		public void ListSmsMessages(string to, string from, DateTime? dateSent, int? pageNumber, int? count, Action<SmsMessageResult> callback)
		{
			var request = new RestRequest();
			request.Resource = "Accounts/{AccountSid}/SMS/Messages";
			request.RootElement = "SMSMessages";

			if (to.HasValue()) request.AddParameter("To", to);
			if (from.HasValue()) request.AddParameter("From", from);
			if (dateSent.HasValue) request.AddParameter("DateSent", dateSent.Value.ToString("yyyy-MM-dd"));
			if (pageNumber.HasValue) request.AddParameter("Page", pageNumber.Value);
			if (count.HasValue) request.AddParameter("PageSize", count.Value);

			ExecuteAsync<SmsMessageResult>(request, (response) => callback(response));
		}

		/// <summary>
		/// Send a new SMS message to the specified recipients
		/// </summary>
		/// <param name="from">The phone number to send the message from. Must be a Twilio-provided or ported local (not toll-free) number. Validated outgoing caller IDs cannot be used.</param>
		/// <param name="to">The phone number to send the message to. If using the Sandbox, this number must be a validated outgoing caller ID</param>
		/// <param name="body">The message to send. Must be 160 characters or less.</param>
		/// <param name="callback">Method to call upon successful completion</param>
		public void SendSmsMessage(string from, string to, string body, Action<SMSMessage> callback)
		{
			SendSmsMessage(from, to, body, null, callback);
		}

		/// <summary>
		/// Send a new SMS message to the specified recipients
		/// </summary>
		/// <param name="from">The phone number to send the message from. Must be a Twilio-provided or ported local (not toll-free) number. Validated outgoing caller IDs cannot be used.</param>
		/// <param name="to">The phone number to send the message to. If using the Sandbox, this number must be a validated outgoing caller ID</param>
		/// <param name="body">The message to send. Must be 160 characters or less.</param>
		/// <param name="statusCallback">A URL that Twilio will POST to when your message is processed. Twilio will POST the SmsSid as well as SmsStatus=sent or SmsStatus=failed</param>
		/// <param name="callback">Method to call upon successful completion</param>
		public void SendSmsMessage(string from, string to, string body, string statusCallback, Action<SMSMessage> callback)
		{
			Validate.IsValidLength(body, 160);
			Require.Argument("from", from);
			Require.Argument("to", to);
			Require.Argument("body", body);

			var request = new RestRequest(Method.POST);
			request.Resource = "Accounts/{AccountSid}/SMS/Messages";
			request.AddParameter("From", from);
			request.AddParameter("To", to);
			request.AddParameter("Body", body);
			if (statusCallback.HasValue()) request.AddParameter("StatusCallback", statusCallback);

			ExecuteAsync<SMSMessage>(request, (response) => callback(response));
		}

		/// <summary>
		/// Retrieve the details for a specific ShortCode instance.
		/// Makes a GET request to a ShortCode Instance resource.
		/// </summary>
		/// <param name="shortCodeSid">The Sid of the ShortCode resource to return</param>
		/// <param name="callback">Method to call upon successful completion</param>
		public void GetShortCode(string shortCodeSid, Action<SMSShortCode> callback)
		{
			Require.Argument("shortCodeSid", shortCodeSid);

			var request = new RestRequest();
			request.Resource = "Accounts/{AccountSid}/SMS/ShortCodes/{ShortCodeSid}";
			request.AddUrlSegment("ShortCodeSid", shortCodeSid);

			ExecuteAsync<SMSShortCode>(request, (response) => callback(response));
		}

		/// <summary>
		/// Tries to update the shortcode's properties, and returns the updated resource representation if successful.
		/// Makes a POST request to the ShortCode instance resource.
		/// </summary>
		/// <param name="shortCodeSid">The Sid of the ShortCode instance to update</param>
		/// <param name="friendlyName">A human readable description of the short code, with maximum length 64 characters.</param>
		/// <param name="apiVersion">SMSs to this short code will start a new TwiML session with this API version.</param>
		/// <param name="smsUrl">The URL that Twilio should request when somebody sends an SMS to the short code.</param>
		/// <param name="smsMethod">The HTTP method that should be used to request the SmsUrl. Either GET or POST.</param>
		/// <param name="smsFallbackUrl">A URL that Twilio will request if an error occurs requesting or executing the TwiML at the SmsUrl.</param>
		/// <param name="smsFallbackMethod">The HTTP method that should be used to request the SmsFallbackUrl. Either GET or POST.</param>
		/// <param name="callback">Method to call upon successful completion</param>
		public void UpdateShortCode(string shortCodeSid, string friendlyName, string apiVersion, string smsUrl, string smsMethod, string smsFallbackUrl, string smsFallbackMethod, Action<SMSShortCode> callback)
		{
			Require.Argument("shortCodeSid", shortCodeSid);

			var request = new RestRequest();
			request.Resource = "Accounts/{AccountSid}/SMS/ShortCodes/{ShortCodeSid}";
			request.AddUrlSegment("ShortCodeSid", shortCodeSid);

			if (friendlyName.HasValue()) request.AddParameter("FriendlyName", friendlyName);
			if (apiVersion.HasValue()) request.AddParameter("ApiVersion", apiVersion);
			if (smsUrl.HasValue()) request.AddParameter("SmsUrl", smsUrl);
			if (smsMethod.HasValue()) request.AddParameter("SmsMethod", smsMethod);
			if (smsFallbackUrl.HasValue()) request.AddParameter("SmsFallbackUrl", smsFallbackUrl);
			if (smsFallbackMethod.HasValue()) request.AddParameter("SmsFallbackMethod", smsFallbackMethod);

			ExecuteAsync<SMSShortCode>(request, (response) => callback(response));
		}

		/// <summary>
		/// Returns a list of ShortCode resource representations, each representing a short code within your account.
		/// </summary>
		/// <param name="shortCode">Only show the ShortCode resources that match this pattern. You can specify partial numbers and use '*' as a wildcard for any digit.</param>
		/// <param name="friendlyName">Only show the ShortCode resources with friendly names that exactly match this name.</param>
		/// <param name="callback">Method to call upon successful completion</param>
		public void ListShortCodes(string shortCode, string friendlyName, Action<SmsShortCodeResult> callback)
		{
			var request = new RestRequest();
			request.Resource = "Accounts/{AccountSid}/SMS/ShortCodes}";

			if (shortCode.HasValue()) request.AddParameter("ShortCode", shortCode);
			if (friendlyName.HasValue()) request.AddParameter("FriendlyName", friendlyName);

			ExecuteAsync<SmsShortCodeResult>(request, (response) => callback(response));
		}
	}
}